﻿#region

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Web.Mvc;
using CuongHanh.Context;
using CuongHanh.DAL;
using CuongHanh.Models;
using CuongHanh.Models.View;

#endregion

namespace CuongHanh.Controllers.FO
{
    public class BaseController : Controller
    {
        public string GetLanguage()
        {
            if(Session[AppUtil.LANGUAGE] != null)
                return Session[AppUtil.LANGUAGE] + "";
            return AppUtil.LANGUAGE_VI;
        }

        public int GetCustomerId()
        {
            int customerId = 0;
            if(Session[AppUtil.CUSTOMERID] != null)
                int.TryParse(Session[AppUtil.CUSTOMERID] + "",
                        out customerId);
            return customerId;
        }


        public IEnumerable<SubCategoryView> GetProductsByFilter(Expression<Func<Product, bool>> filter = null)
        {
            string l = GetLanguage();
            IEnumerable<Product> query = CacheContext<Product>.Singleton.GetObjectsByFilter(filter);
            IEnumerable<Category> categories = CacheContext<Category>.Singleton.GetObjectsByFilter();
            IEnumerable<SubCategory> subCategories = CacheContext<SubCategory>.Singleton.GetObjectsByFilter();
            var products = query.Join(categories,
                    c => c.CategoryId,
                    v => v.Id,
                    (c,
                            v) => new
                                  {
                                          c,
                                          v
                                  })
                    .Join(subCategories,
                            c => c.c.SubCategoryId,
                            v => v.Id,
                            (c,
                                    v) => new
                                          {
                                                  c.c.Id,
                                                  c.c.Code,
                                                  Name = l == AppUtil.LANGUAGE_EN
                                                                  ? c.c.NameEn
                                                                  : c.c.NameVi,
                                                  CategoryName = l == AppUtil.LANGUAGE_EN
                                                  ? c.v.NameEn
                                                  : c.v.NameVi,
                                                  SubCategoryName = l == AppUtil.LANGUAGE_EN
                                                                  ? v.NameEn
                                                                  : v.NameVi,
                                                  c.c.Price,
                                                  c.c.SaleOff,
                                                  c.c.CategoryId,
                                                  c.c.SubCategoryId,
                                                  c.c.Image,
                                                  CategoryNo = c.v.No,
                                                  SubCategoryNo = v.No
                                          })
                    .OrderBy(c => c.CategoryNo).ThenBy(c => c.SubCategoryNo).ToList();

            List<SubCategoryView> productViews = new List<SubCategoryView>();
            int subCategoryId = 0;
            SubCategoryView subCategoryView = new SubCategoryView();
            foreach (var product in products)
            {
                if(subCategoryId != product.SubCategoryId)
                {
                    subCategoryView = new SubCategoryView(product.SubCategoryId);
                    subCategoryView.Name = product.SubCategoryName;
                    subCategoryView.CategoryName = product.CategoryName;
                    subCategoryId = product.SubCategoryId;
                    productViews.Add(subCategoryView);
                }
                subCategoryView.ProductView.Add(new ProductView(product.Id,
                        product.Code,
                        product.Name,
                        product.Price,
                        product.SaleOff,
                        product.Image,
                        ""));
            }
            return productViews;
        }

        public ProductView GetProductDetail(UnitOfWork unitOfWork,
                int id,
                int branchId)
        {
            string l = GetLanguage();
            Product product = unitOfWork.FirstOrDefault<Product>(c => c.Id == id && c.BranchId == branchId && !c.Inactive && !c.Invisible) ?? new Product();
            ProductView result = new ProductView(product.Id,
                    product.Code,
                    l == AppUtil.LANGUAGE_VI
                            ? product.NameVi
                            : l == AppUtil.LANGUAGE_EN
                                    ? product.NameEn
                                    : l == AppUtil.LANGUAGE_ZH
                                            ? product.NameZh
                                            : product.NameVi,
                    product.Price,
                    product.SaleOff,
                    product.Image,
                    product.Article
                    )
                                 {
                                         Images = unitOfWork.Where<ProductImage>(c => c.ProductId == id && !c.Inactive).Select(c => c.Image).ToList()
                                 };
            return result;
        }

        public IEnumerable<SubCategoryView> GetProductBestSaler(UnitOfWork unitOfWork,
                int count,
                Expression<Func<Product, bool>> filter = null)
        {
            string l = GetLanguage();
            IQueryable<Product> query = unitOfWork.Where<Product>();
            if(filter != null)
                query = query.Where(filter);
            var products = query.Select(c => new
                                             {
                                                     c.Id,
                                                     c.Code,
                                                     Name = l == AppUtil.LANGUAGE_VI
                                                             ? c.NameVi
                                                             : l == AppUtil.LANGUAGE_EN
                                                                     ? c.NameEn
                                                                     : l == AppUtil.LANGUAGE_ZH
                                                                             ? c.NameZh
                                                                             : c.NameVi,
                                                     c.Price,
                                                     c.SaleOff,
                                                     c.CategoryId,
                                                     c.SubCategoryId,
                                                     c.Image
                                             }).OrderBy(c => c.CategoryId).ThenBy(c => c.SubCategoryId).Skip(0).Take(count).ToList();

            List<ProductView> productViews = new List<ProductView>();

            foreach (var product in products)
            {
                productViews.Add(new ProductView(product.Id,
                        product.Code,
                        product.Name,
                        product.Price,
                        product.SaleOff,
                        product.Image,
                        ""));
            }
            List<SubCategoryView> models = new List<SubCategoryView>();
            models.Add(new SubCategoryView(0)
                       {
                               ProductView = productViews
                       });
            return models;
        }

        public IEnumerable<SubCategoryView> GetProductByPageIndexs(UnitOfWork unitOfWork,
                int start,
                int limit,
                Expression<Func<Product, bool>> filter = null)
        {
            string l = GetLanguage();
            IQueryable<Product> query = unitOfWork.Where<Product>();
            if(filter != null)
                query = query.Where(filter);
            var products = query.Select(c => new
                                             {
                                                     c.Id,
                                                     c.Code,
                                                     Name = l == AppUtil.LANGUAGE_VI
                                                             ? c.NameVi
                                                             : l == AppUtil.LANGUAGE_EN
                                                                     ? c.NameEn
                                                                     : l == AppUtil.LANGUAGE_ZH
                                                                             ? c.NameZh
                                                                             : c.NameVi,
                                                     c.Price,
                                                     c.SaleOff,
                                                     c.CategoryId,
                                                     c.SubCategoryId,
                                                     c.Image
                                             }).OrderBy(c => c.CategoryId).ThenBy(c => c.SubCategoryId).Skip(start).Take(limit).ToList();

            List<SubCategoryView> productViews = new List<SubCategoryView>();
            int subCategoryId = 0;
            SubCategoryView subCategoryView = new SubCategoryView();
            foreach (var product in products)
            {
                if(subCategoryId != product.SubCategoryId)
                {
                    subCategoryView = new SubCategoryView(product.SubCategoryId);
                    subCategoryId = product.SubCategoryId;
                    productViews.Add(subCategoryView);
                }
                subCategoryView.ProductView.Add(new ProductView(product.Id,
                        product.Code,
                        product.Name,
                        product.Price,
                        product.SaleOff,
                        product.Image,
                        ""));
            }
            return productViews;
        }

        private Bitmap GetProductImageByType(string imageName,
                ImageType imageType)
        {
            int descWidth = 0,
                    descHeight = 0;
            switch (imageType)
            {
                case ImageType.Thumnail:
                    descWidth = 48;
                    descHeight = 48;
                    break;
                case ImageType.Small:
                    descWidth = 290;
                    descHeight = 290;
                    break;
                case ImageType.Large:
                    descWidth = 850;
                    descHeight = 850;
                    break;
            }

            Bitmap mergeImage = new Bitmap(descWidth,
                    descHeight,
                    PixelFormat.Format32bppArgb);

            Graphics graphics = Graphics.FromImage(mergeImage);
            graphics.CompositingMode = CompositingMode.SourceOver; // this is the default, but just to be clear
            graphics.FillRectangle(new SolidBrush(Color.White),
                    0,
                    0,
                    descWidth,
                    descHeight);
            string path = HttpContext.Server.MapPath((Path.Combine(AppUtil.LARGE_IMAGE_PATH,
                    imageName)));
            if(!System.IO.File.Exists(path))
                return mergeImage;
            Bitmap pic1 = new Bitmap(path);
            graphics.DrawImage(pic1,
                    new Rectangle(0,
                            0,
                            descWidth,
                            descHeight),
                    0,
                    0,
                    pic1.Width,
                    pic1.Height,
                    GraphicsUnit.Pixel);
            return mergeImage;
        }

        public ActionResult GetProductImage(string productName,
                string imageName,
                ImageType imageType)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                GetProductImageByType(imageName,
                        imageType).Save(ms,
                                ImageFormat.Jpeg);
                ms.WriteTo(HttpContext.Response.OutputStream);
                return File(ms.ToArray(),
                        "image/jpg",
                        string.Format("{0}.jpg",
                                productName));
            }
        }
    }
}
